/**
ProxyUtils.java
jackysoft-basic-core
2012-7-31上午9:44:35
@author 屈甲康
@QQ285799123
mailto:qujiakang@126.com
**/
package org.jackysoft.util;

import java.lang.reflect.Field;

import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.support.AopUtils;

public class ProxyUtils {
    public static Object getAopTarget(Object proxy) throws Exception{
    	if(!AopUtils.isAopProxy(proxy)){
    		return proxy;
    	}
    	if(AopUtils.isJdkDynamicProxy(proxy)){
    		return getJdkDynamicProxy(proxy);
    	}else{
    		return getCglibProxyTargetObject(proxy);
    	}
    }

	private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
		Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
		h.setAccessible(true);
		Object dynamicAdvisedInterceptor = h.get(proxy);
		Field  advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
		advised.setAccessible(true);
		Object target = ((AdvisedSupport) advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
		return target;
	}

	private static Object getJdkDynamicProxy(Object proxy) throws Exception{
		Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
		h.setAccessible(true);
		AopProxy aopProxy = (AopProxy) h.get(proxy);
		Field advised = aopProxy.getClass().getDeclaredField("advised");
		advised.setAccessible(true);
		Object target = ((AdvisedSupport) advised.get(aopProxy)).getTargetSource().getTarget();
		return target;
	}
}
